/**
 * axios封装
 * 请求拦截、响应拦截、错误统一处理
 */
import axios from "axios";
import { Message } from "element-ui"; // 单独引入elementUI的消息提示框组件
import store from "../store/index";
import { quitFun } from "@/util/quit";
// import nprogress from 'nprogress' // progress bar
// import 'nprogress/nprogress.css'// progress bar style
// nprogress.configure({ showSpinner: false })// NProgress Configuration

/**
 * 提示函数
 * 禁止点击蒙层、显示一秒后关闭
 */
const sptoken = sessionStorage.getItem("sptoken");
const tip = (msg, type) => {
  Message({
    message: msg,
    type: type,
  });
};

/**
 * 请求失败后的错误统一处理
 * @param {Number} status 请求失败的状态码
 */
const errorHandle = (response) => {
  let status = response.status;
  let other = response.data.message;
  // 状态码判断
  switch (status) {
    // case 400:
    //   Message({
    //     message: '参数有误',
    //     type: "error",
    //     duration: 1000,
    //     showClose: true
    //   })
    //   break
    // 401: 未登录状态，跳转登录页
    case 401:
      tip("登录过期，请重新登录", "error");
      setTimeout(() => {
        //quitFun();
      }, 1000);
      break;
    case 403:
      tip("登录过期，请重新登录", "error");
      setTimeout(() => {
        quitFun();
      }, 1000);
      break;
    // 404请求不存在
    case 404:
      tip("请求的资源不存在", "error");
      break;
    case 405:
      // tip("您目前的操作有爬虫的嫌疑，请稍后再试！", "error");
      break;
    default:
      // eslint-disable-next-line no-console
      //后台错误提示
      if (other) {
        tip(other, "warning");
      }
  }
};

// 创建axios实例
var instance = axios.create({ timeout: 1000 * 60 * 60 * 2 });
// 设置post请求头
instance.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
// instance.defaults.headers.put['Content-Type'] = 'multipart/form-data'

instance.defaults.headers["Authorization"] = "Bearer " + sptoken || ""; // 设置请求头

instance.defaults.responseType = "json";
//设置全局的请求次数，请求的间隙
instance.defaults.retry = 3; // 请求次数
instance.defaults.retryDelay = 2000; //请求间隙

instance.interceptors.request.use(
  (config) => {
    //config是axios配置对象
    //每次发送请求前都会进入此拦截器处理函数，可以在此处统一携带上token，每次请求都会自
    if (config.url.includes("Approve/ExportApproveDetail")) {
      config.responseType = "blob";
    }
    return config;
  },
  (err) => {
    //请求出错的处理函数
    return Promise.reject(err);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  // 请求成功
  (res) => {
    return Promise.resolve(res);
  },
  // 请求失败
  (error) => {
    // nprogress.done() // 进度条结束
    const { response } = error;
    console.log(error, "error");
    console.log(response, "response");
    if (response) {
      // 请求已发出，但是不在2xx的范围
      errorHandle(response);
      return Promise.reject(response);
    } else {
      // 处理断网的情况
      // eg:请求超时或断网时，更新state的network状态
      // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
      // 关于断网组件中的刷新重新获取数据，会在断网组件中说明
      if (error.message.includes("timeout")) {
        tip("请求超时，请稍后", "error");
        return Promise.reject(error);
      }
      console.log("处理断网的情况处理断网的情况处理断网的情况处理断网的情况处理断网的情况");
      var config = error.config;
      config.retry = 3;
      config.retryDelay = 1000;
      // 设置用于跟踪重试计数的变量
      config.__retryCount = config.__retryCount || 0;

      if (!window.navigator.onLine && config.__retryCount >= config.retry) {
        // store.commit('changeNetwork', false)
        tip("您的网络不稳定，请检查网络", "error");
        return Promise.reject(error);
      }
      if (config.__retryCount >= config.retry) {
        tip("网络异常，请稍后重试", "error");
        return Promise.reject(error);
      }
      // 增加重试次数
      config.__retryCount += 1;
      // 创建新的承诺来处理指数后退
      var backoff = new Promise(function (resolve) {
        setTimeout(function () {
          resolve();
        }, config.retryDelay || 1);
      });
      // 返回调用axios以重试请求的承诺
      return backoff.then(function () {
        return instance(config);
      });
    }
  }
);

export default instance;
